perm filename AIMEMO[C,JRA] blob sn#020486 filedate 1973-01-10 generic text, type T, neo UTF8


		   Progress Report -- Teaching of Procedures

			     by Gerald Jay Sussman



	   The idea of building a programmer is very seductive in that it

   holds the promise of massive bootstrapping and thus ties in with many

   ideas about learning and teaching.  I will avoid going into those issues

   here. It is necessary, however, to explain what I am not working on. I am

   not interested in developing new and better languages for expressing

   algorithms. When FORTRAN was invented, it was touted as an automatic

   programmer, and indeed it was, as it relieved the user of complete

   specification of the details of implementation.  Newer programming

   languages are just elaborations (usually better) of that basic idea. I

   am, however, interested in the problem of implementation of a Partially
   rather than a complete algorithm and a partially   specified algorithm

   specified implementation.  This problem is truly in the domain of

   Artificial Intelligence because the system which "solves" this problem

   needs a great deal of knowledge about the problem domain for which the

   algorithm is being constructed in order to "reasonably" complete the

   specification.   Indeed, a programmer is not told exactly the algorithm

   to be implemented, he is told the problem which his program is expected

   to solve.

	   A programmer hardly ever starts with no program at all. Usually,

   he has a program which is almost but not quite applicable to the need. In

   this case, the programmer determines how the given program is to be

   modified to display the desired behavior; he makes a patch. This





								      PAGE 2
   technique is closely related to debugging, in which a program designed to

   solve a known problem misbehaves in some case. The bug must be understood

   and a patch concocted. In general, under good conditions, the creation of

   a program to solve some problem can be viewed as debugging an existing

   program.

	   Thus, the purpose of this project is to produce a "programmer." I

   am relying deeply on introspective concepts of how I do programming. 


								      PAGE 3


   I. Automatic Program Construction



	   I have been constructing a program called "HACKER" which writes

   and debugs programs in the BLOCKS world. It currently shows signs of

   life, writing some elementary programs by debugging and patching. The

   program HACKER as well as the programs it operates on are written in

   CONNIVER.

	   The physics of the BLOCKS world is as follows: there are blocks

   on a table and a hand. The hand can lift only one block at a time. Hence

   the hand cannot lift a block if there are others on it. A block can only

   be placed on another if there is enough space on the other.  Here we

   introduce one primitive which moves blocks in this world.  (PUTON A B)

   puts block A on block B if A's top is clear and B has space for A on it,

   otherwise it produces an error. HACKER does not consider the structure of

   PUTON just as I don't think about CONS. HACKER does, however, know about

   PUTON and gets the error comments from it when it is incorrectly called.

   HACKER starts out with one well-commented but very limited program to

   work with:



   (IF-NEEDED I-F-ON (IMPERATIVE-FOR (ON !>(X (ATOM !,X)) !>(Y (ATOM !,Y))))

	      (NEEDS (AND (CLEARTOP !,X) (SPACE-FOR !,X !,Y))

		     (PUTON X Y))

	      (ADIEU 'OK))


								      PAGE 4


   This program is called by pattern-directed invocation; if we need an

   imperative for getting atomic object X (not a tower) on an atomic object

   Y, it is called. Its body consists of a call to PUTON commented by its

   prerequisites. The (ADIEU 'OK) informs the caller of success.



   HACKER also knows:



   (IF-NEEDED M-O-CLEARTOP

	   (MEANING-OF (CLEARTOP !'X)

		       (NOT (EXISTS !,(Y (GENSYM))

				      (ON !,Y !,X))))

	   (NOTE))



   i.e. cleartop(x)	 y . . on(y,x)



   (IF-NEEDED S-F-NOT-ON

	   (SUFFICES-FOR (NOT (ON !'X !'Y))

		   (EXISTS !,(Z (GENSYM))

			    (WHERE (ON !,X !,Z) (NOT (= !,Z !,Y)))))

	   (NOTE))



   i.e.     z=y . . on(x,z)    on(x,y)	     /



   Further concepts will be introduced as needed. In section II (Heuristic

   Programming) we will deal with more difficult concepts concerned with


								      PAGE 5


   space.



	   We talk to HACKER by asking it to achieve a desired final state,

   e.g. (ACHIEVE (ON A B)) or, say (ACHIEVE (AND (ON A B) (ON B C))).

   ACHIEVE first tests if its goal is already achieved and if so it returns

   OK.   If not, it searches for a way to accomplish the goal.  

	   Consider (ACHIEVE (ON A B)). If A has a clear top and there is

   space for A on B, then when I-F-ON is invoked, it calls (PUTON 'A 'B)

   which does the job.  Suppose, however, the situation was:



					   (ON A TABLE)

					   (ON B TABLE)

					   (ON C A)



   I-F-ON is invoked, it calls PUTON. PUTON gets angry and returns the error

   comment:

	   UNSATISFIED PREREQUISITE (NOT (ON C A))

   HACKER then backtraces, checking the truth of the comment (NEEDS (AND

   (CLEARTOP ,X) (SPACE-FOR ,X ,Y))...). It finds it untrue. Since this is a

   NEEDS comment, it writes code to achieve the prerequisites and patches it

   in.  Now I-F-ON looks like this:


								      PAGE 6


   (IF-NEEDED I-F-ON (IMPERATIVE-FOR (ON !>(X (ATOM ,X)) !>(Y (ATOM ,Y)))

       (SETUP (CODE-FOR (AND (CLEARTOP !,X) (SPACE-FOR !,X !,Y))

			(PROG "AUX" ((PROTECTEDS NIL))

			      (PROG (ACHIEVE (CLEARTOP !,X))

				    (PROTECT (CLEARTOP !,X)))

			      (PROG (ACHIEVE (SPACE-FOR !,X !,Y))

				    (PROTECT (SPACE-FOR !,X !,Y)))

			      (UNPROTECT PROTECTEDS)))

	      (PUTON X Y)))



   SETUP is a comment explaining the reasons for the code written; to setup

   for (PUTON X Y). CODE-FOR is a comment explaining that its second

   argument was written to achieve the first argument. The code written

   binds a variable PROTECTEDS and initializes it to NIL. It then achieves

   and protects each subgoal, unprotecting them before leaving. Protection

   is a mechanism for catching bugs of interaction between subgoals (to be

   explained later).

	   This code was generated by a process I call pattern-directed

   macro-expansion from a macro in HACKER'S bag of coding tricks. (The

   concepts of a "bag of tricks" is due to Richard Greenblatt). This trick

   is fairly complex and looks like:


								      PAGE 7


   (IF-NEEDED C-F-AND (CODE-FOR (AND . !'L) !<CODE)

       "AUX" ((P NIL))

       (FOR-EACH-ELEMENT G L

	    (CSETQ P (CONS (LIST 'PROG (LIST 'ACHIEVE G)

					(LIST 'PROTECT G))

			     P)))

       (CSETQ CODE (APPEND '(PROG "AUX" ((PROTECTEDS NIL)))

			   (REVERSE P)

			   '((UNPROTECT PROTECTEDS))))

       (NOTE))



   The complexity stems from the ability to code for AND of any number of

   elements.   HACKER then backs up the stack and starts running from

   (SETUP...).   He gets to (ACHIEVE (CLEARTOP !,X)) before running into

   trouble.   (CLEARTOP A) is not true so he looks for an imperative for

   cleartop.   Not finding any he realizes it's time to write some code.

   Finding M-O-CLEARTOP he sees that CLEARTOP is a defined concept and thus

   he writes, by pattern-directed macro-expansion:



   (IF-NEEDED (IMPERATIVE-FOR (CLEARTOP !>X))

	      (MEANING-OF (CLEARTOP !,X)

			 (ACHIEVE (NOT (EXISTS Z1 (ON Z1 !,X)))))

	      (ADIEU 'OK))



								      PAGE 8


   HACKER then runs the new imperative but he needs to achieve the not

   exists expression.  It is not yet true, has no imperative, has no

   explicit meaning, but we  have a trick for this case:



   (IF-NEEDED (CODE-FOR (NOT (EXISTS !>V !'G))

			(FOR-EACH !,V !<G1

				  (ACHIEVE (NOT !<G2))))

	      (CSETQ G1 (SUBST (LIST '/!/; V) V G)

		     G2 (SUBST (LIST '/!/, V) V G))

	      (NOTE))



   Thus we expand the ACHIEVE, patching to get:



   (IF-NEEDED (IMPERATIVE-FOR (CLEARTOP !>X))

	      (MEANING-OF (CLEARTOP !,X)

			  (CODE-FOR (NOT (EXISTS Z1 (ON Z1 !,X)))

				    (FOR-EACH Z1 (ON !Z1 !,X)

					 (ACHIEVE (NOT (ON !,Z1 !,X))))))

	      (ADIEU 'OK))



   FOR-EACH is a canned loop commonly found in CONNIVER programs. This code

   is run until it hits the expression (ACHIEVE (NOT (ON !,Z1 !,X)).  Here

   we expand the macro S-F-NOT-ON getting:



								     PAGE 9


   (IF-NEEDED (IMPERATIVE -FOR (CLEARTOP !X))

       (MEANING-OF (CLEARTOP !,X)

	       (CODE-FOR (NOT (EXISTS Z1 (ON Z1 !,X)))

			 (FOR-EACH Z1 (ON !Z1 !,X)

			     (SUFFICES-FOR (NOT (ON !,Z1 !,X))

				 (ACHIEVE (EXISTS Z2

					     (WHERE (ON !,Z1 !,Z2)

						    (NOT (= !,Z2 !,X))))))

	      (ADIEU 'OK))



   We run this new code until we have to expand the expression (ACHIEVE

   (EXISTS ...)). Here we need the trick:



   (IF-NEEDED (CODE-FOR (EXISTS !V (WHERE !'G !'Q))

	      (PROG "AUX" (!,V)

		    (CHOOSE !,V !,Q (POSSIBLE !,G))

		    (ACHIEVE !,G)))

	      (NOTE))



   Thus we get:


								     PAGE 10


   (IF-NEEDED (IMPERATIVE-FOR (CLEARTOP !X))

       (MEANING-OF (CLEARTOP !,X)

	   (CODE-FOR (NOT (EXISTS Z1 (on Z1 !,X)))

	       (FOR-EACH Z1 (ON !Z1 !,X)

		   (SUFFICES-FOR (NOT (ON !,Z1 !,X))

		       (CODE-FOR (EXISTS Z2 (WHERE (ON !,Z1 !,Z2)

					    (NOT (= !,Z2 !,X))))

				 (PROG "AUX" (Z2)

				       (CHOOSE Z2 (NOT (= !,Z2 !,X))

						  (POSSIBLE (ON !,Z1 !,Z2)))

				       (ACHIEVE (ON !,Z1 !,Z2))))))))

       (ADIEU 'OK))



   This code runs, CHOOSE (by magic of its own) makes Z2=TABLE.  (ACHIEVE

   (ON C TABLE)) (remember Z1=C) finds I-F-ON and calls it recursively,

   solving the problem. 

	   Note that by just running this specific example we get I-F-ON

   patched for situations where X is not CLEARTOP and a completely general

   CLEARTOP routine which not only solves this specific case but also any

   recursively or iteratively complex example.  E.g. the performance program

   can now, without modification achieve (CLEARTOP A) in:




								     PAGE 11


   Note also that the knowledge used in writing this program is divided into

   two independent classes:

	   1) Knowledge of the proglem domain:  

	      I-F-ON, M-O-CLEARTOP, S-F-NOT-ON

	   2) Domain independent programming knowledge: 

	      i.e. all CODE-FOR methods.

   It is my hope and honest belief, that almost all "programming" knowledge

   can be coded into a small number (perhaps 50) coding tricks. New problem

   domain dependent knowledge can be easily added; for instance, I can

   define the concept of a 3-tower as:  



   (IF-NEEDED (MEANING-OF (3-TOWER !'X !'Y !'Z)

			  (AND (ON !,X !,Y) (ON !,Y !,Z))))




								     PAGE 12


   II. Heuristic Programming



	   So far we have been dealing with well-defined and understood

   concepts like CLEARTOP (which even has an explicit definition), NOT-

   ONness (for which we have a sufficient condition) and ONness. The blocks

   world also contains a much fuzzier concept, SPACE-FOR, which we can not

   so clearly work out. For achieving CLEARTOP, there is only one program.

   If it cannot do the job there is no hope. For SPACE-FOR, however, we have

   various strategies which can be tried, no one of which is guaranteed to

   work, nor is the failure of one an indication of ultimate failure. We now

   investigate the methods required to handle such concepts and the

   constructs which are entailed.

	   Suppose that the scene is:



					   (ON A TABLE)

					   (ON B TABLE)

					   (ON C B)



   and we want to put A on B. (CLEARTOP A) is true but we get stuck at

   (SPACE-FOR A B). Since it has no direct route to achieving the goal,

   HACKER looks around for a way to assign blame for this failure. Here we

   introduce a new set of facts.



								     PAGE 13


   (IF-NEEDED M-H-SPACE-FOR-1

      (MAY-HURT (SPACE-FOR !'X !'Y) (CLUTTERED !,Y))

      (NOTE))



   (IF-NEEDED M-O-CLUTTERED

      (MEANING-OF (CLUTTERED !'X)

	     (EXISTS !,(Y (GENSYM)) (WHERE (ON !,Y !,X)

					   (NOT (PROTECTED (ON !,Y !,X))))))

      (NOTE))



   (IF-NEEDED M-H-SPACE-FOR-2

      (∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈∧␈e of C (a heuristic to maximize stability).  This blocks the

   (SPACE-FOR B C) becuase C isn't large enough to hold B with A on its

   middle. What does HACKER do? The performance program is in (STRATEGY-FOR

								     PAGE 19


   (SPACE-FOR B C) ... ) when it discovers that it cannot win by the clutter

   strategy as (ON A C) is protected.  Since there are no other strategies

   currently coded, STRATEGY-FOR asks HACKER for help. HACKER finds another

   strategy, M-H-SPACE-FOR-2; the HAPHAZARD strategy, and finds, indeed,

   that (HAPHAZARD C) is true. This is then coded up as before as an

   alternative strategy: (from now on I will leave out details of expansion,

   filling in with ... and only showing relevant segments.)


   (STRATEGY-FOR (SPACE-FOR !,X !,Y)

      (MEANING-OF (NOT (CLUTTERED !,Y)) ... )

      (MEANING-OF (NOT (HAPHAZARD !,Y)) ... ))



   This code indeed solves the problem but we must introduce some more

   primitives.  



   (IF-NEEDED (IMPERATIVE-FOR (PACKED !X !Y))

      (NEEDS (CLEARTOP !,X) (PACK X Y))

      (ADIEU 'OK))





   (IF-NEEDED (SUFFICES-FOR (NOT (BADLY-PLACED !'X !'Y)) (PACKED !,X !,Y))

      (NOTE))



   Note: STRATEGY-FOR takes any number of strategies and exhausts them in

   the given order.

								     PAGE 20


   Note: PACK pushes its first argument as far as it can from the center of

   its second argument, without falling off.

	   This patch, though it works in this case, and is often useful, is

   not a good patch.  In fact, HACKER realizes the trouble quickly. We see

   that in running the patch, A is pushed to a corner of C. But A was the

   last object moved, (HACKER keeps a record of this) and if an object is

   moved twice with no intervening other manipulations, it should have been

   moved to the correct place the first time. This is not just a matter of

   efficiency -- if the problem had been: (AND (ON A C) (ON D A) (ON B C)

   (ON E B)) we would have had trouble pushing the towers (D A) or (E B).

   Though there is a permutation of the AND which will work, the problem is

   compounded with compound objects (not yet discussed) as in (AND (ON

   (TOWER D A) C) (ON  (TOWER E B) C)). In any case, HACKER has an eye

   peeled (an interrupt set) for double movements in execution of a single

   command. He allows the execution to proceed but leaves a note to himself

   to investigate the problem when the command returns successfully. Each

   time an object is moved, the "physics" leaves a note on the HISTORY list

   with the activation of the mover.  Thus when the program successfully

   returns HACKER sees that the first mover of A was:

   (PUTON A C) called by (ACHIEVE (ON A C))

   and that the second was: (PACK A C) which left A in a good position.

   Thus he edits the first goal to read: (ACHIEVE (ON A C PACK)) which will

   put it down packed the first time (I lied to you about I-F-ON and PUTON:

   they really have an optional position defining argument whose default is

   "center").   


								     PAGE 21


	   The DEBUGGING knowledge appearing in this section is not as

   explicitly stated as in the preceeding sections because it is not yet

   coded. A major criterion for the code is that it break up into BLOCKS and

   programming knowledge.